package com.ebei.admin.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ebei.admin.common.constant.Constants;
import com.ebei.admin.common.util.AuthRealm;
import com.ebei.admin.common.util.TreeUtil;
import com.ebei.admin.mapper.SysMenuMapper;
import com.ebei.admin.model.dto.MenuTree;
import com.ebei.admin.model.entity.SysMenu;
import com.ebei.admin.service.SysMenuService;
import com.ebei.common.constant.CommonConstant;
import com.ebei.common.util.Assert;
import com.ebei.common.vo.MenuVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 菜单服务实现类
 *
 * @author crazypenguin
 * @version 1.0
 * @created 2018/4/17
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    @Cacheable(value = "menu_details", key = "#role  + '_menu'")
    public Set<MenuVO> findMenuByRole(String role) {
        Map<String, Object> params = new HashMap<>();
        params.put("role",role);
        return sysMenuMapper.findMenus(params);
    }

    @Override
    public String[] findPermission(String[] roles) {
        Set<MenuVO> menuVoSet = new HashSet<>();
        for (String role : roles) {
            Set<MenuVO> menuVos = findMenuByRole(role);
            menuVoSet.addAll(menuVos);
        }

        Set<String> permissions = new HashSet<>();
        for (MenuVO menuVo : menuVoSet) {
            if (StringUtils.isNotEmpty(menuVo.getPermission())) {
                String permission = menuVo.getPermission();
                permissions.add(permission);
            }
        }

        return permissions.toArray(new String[permissions.size()]);
    }

    @Override
    @CacheEvict(value = "menu_details", key = "#role + '_menu'")
    public Boolean deleteMenu(Integer id, String role) {
        // 删除当前节点
        SysMenu condition1 = new SysMenu();
        condition1.setMenuId(id);
        condition1.setDelFlag(CommonConstant.STATUS_DEL);
        return this.updateById(condition1);
    }

    @Override
    @CacheEvict(value = "menu_details", key = "#role + '_menu'")
    public Boolean updateMenuById(SysMenu sysMenu, String role) {
        return this.updateById(sysMenu);
    }

    /**
     * 返回角色的菜单
     *
     * @param roleName 角色
     * @return 菜单列表
     */
    @Override
    public List<MenuTree> findUserMenuTree(String roleName) {
        // 获取符合条件得菜单
        Set<MenuVO> all = findMenuByRole(roleName);
        final List<MenuTree> menuTreeList = new ArrayList<>();
        all.stream().forEach((menuVo -> {
            if (CommonConstant.MENU.equals(menuVo.getMenuType())) {
                menuTreeList.add(new MenuTree(menuVo));
            }
        }));
        return TreeUtil.bulid(menuTreeList, -1);
    }

    @Override
    public List<MenuTree> findMenuTreeByRoleNameAndDeviceType(String roleName,String deviceType) {
        // 超级管理员查询所有菜单
        List<SysMenu> allMenus = new ArrayList<>();
        if(AuthRealm.isSpAdmin()){
            SysMenu condition = new SysMenu();
            condition.setDelFlag(CommonConstant.STATUS_NORMAL);
            condition.setDeviceType(deviceType);
            allMenus = this.selectList(new EntityWrapper<>(condition));
        }else{
            // 政府看到角色为【园区管理员】的菜单
            if(Constants.TYPE_GOV.equals(AuthRealm.getPrincipal().getType())){
                Set<MenuVO> roleMenus = findMenuByRoleAndDeviceType(Constants.PARK_ADMIN,deviceType);
                SysMenu sysMenu;
                for(MenuVO menuVO : roleMenus){
                    sysMenu = new SysMenu();
                    BeanUtils.copyProperties(menuVO,sysMenu);
                    allMenus.add(sysMenu);
                }
            }
            // 企业看到角色为【企业管理员】的所有菜单
            else if(Constants.TYPE_COM.equals(AuthRealm.getPrincipal().getType())){
                Set<MenuVO> roleMenus = findMenuByRoleAndDeviceType(Constants.COMPANY_ADMIN,deviceType);
                SysMenu sysMenu;
                for(MenuVO menuVO : roleMenus){
                    sysMenu = new SysMenu();
                    BeanUtils.copyProperties(menuVO,sysMenu);
                    allMenus.add(sysMenu);
                }
            }
        }



        // 查询角色所拥有菜单
        Set<MenuVO> roleMenus = findMenuByRole(roleName);
        List<Integer> menuList = new ArrayList<>();
        for (MenuVO menuVo : roleMenus) {
            menuList.add(menuVo.getMenuId());
        }

        // 转化为树
        List<MenuTree> menuTreeList = new ArrayList<>();
        MenuTree menuTree;
        for(SysMenu menu : allMenus){
            menuTree = new MenuTree();
            menuTree.setId(menu.getMenuId());
            menuTree.setParentId(menu.getParentId());
            menuTree.setName(menu.getMenuName());
            if(menuList.contains(menu.getMenuId())){
                menuTree.setChecked(true);
            }else{
                menuTree.setChecked(false);
            }
            menuTreeList.add(menuTree);
        }

        return TreeUtil.bulid(menuTreeList, -1);
    }

    /**
     * 根据角色和设备类型查询菜单
     * @param role
     * @param deviceType
     * @return
     */
    private Set<MenuVO> findMenuByRoleAndDeviceType(String role, String deviceType){
        Map<String, Object> params = new HashMap<>();
        params.put("role",role);
        params.put("deviceType",deviceType);
        return sysMenuMapper.findMenus(params);
    }

    @Override
    public Integer getSort(Integer parentId,String deviceType) {
        SysMenu condition = new SysMenu();
        condition.setParentId(parentId);
        condition.setDeviceType(deviceType);
        condition.setDelFlag(CommonConstant.STATUS_NORMAL);
        // 获取同级节点list
        List<SysMenu> sysMenuList = this.selectList(new EntityWrapper<>(condition));
        if(sysMenuList!=null){
            return sysMenuList.size() + 1;
        }else{
            return 1;
        }
    }

    @Override
    public List<MenuVO> selectMenuListByUserId(Map<String,Object> params) {
        return sysMenuMapper.selectMenuListByUserId(params);
    }
}
